<?php
/**
 * Handles all Tax relates Queries
 * @copyright Nicolas Schudel 2008
 * @copyright Portions Copyright 2003-2006 Zen Cart Development Team
 * @copyright Portions Copyright 2003 osCommerce
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
 */

class Taxes {
	private $db;
	private $currencies;
	
	private $displayPriceWithTax;
	private $defaultCurrency;
	
	function __construct() {
		$this->db = ServiceLocator::getService('ConnectionFactory');
		$this->cf = ServiceLocator::getService('Configuration');
		$this->currencies = ServiceLocator::getService( 'Currencies' );
		
		$this->db->connect($this->cf->get('DB_SERVER'), $this->cf->get('DB_SERVER_USERNAME'), $this->cf->get('DB_SERVER_PASSWORD'), $this->cf->get('DB_DATABASE'), $this->cf->get('DB_USE_PCONNECT'), false);
		
		$this->displayPriceWithTax = $this->cf->get('DISPLAY_PRICE_WITH_TAX');
		$this->defaultCurrency = $this->currencies->getDefaultCurrency();
	}
	
	public function getTaxAddress() {
		$tax_basis_query =	"SELECT cf.configuration_value FROM " . $this->cf->get('TABLE_CONFIGURATION') . " cf WHERE configuration_key = 'STORE_PRODUCT_TAX_BASIS'";
						
		$tax_basis = $this->db->execute($tax_basis_query);
		
		switch ($tax_basis->fields['configuration_value']) {
			case 'Shipping':
		
			$tax_address_query = "select ab.entry_country_id, ab.entry_zone_id
															from " . $this->cf->get('TABLE_ADDRESS_BOOK') . " ab
															left join " . $this->cf->get('TABLE_ZONES') . " z on (ab.entry_zone_id = z.zone_id)
															where ab.customers_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'
															and ab.address_book_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'";
			$tax_address = $this->db->execute($tax_address_query);
			break;
			case 'Billing':
			$tax_address_query = "select ab.entry_country_id, ab.entry_zone_id
															from " . $this->cf->get('TABLE_ADDRESS_BOOK') . " ab
															left join " . $this->cf->get('TABLE_ZONES') . " z on (ab.entry_zone_id = z.zone_id)
															where ab.customers_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'
															and ab.address_book_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'";
			$tax_address = $this->db->execute($tax_address_query);
			break;
			case 'Store':
			if ($billing_address->fields['entry_zone_id'] == STORE_ZONE) {
		
				$tax_address_query = "select ab.entry_country_id, ab.entry_zone_id
										from " . $this->cf->get('TABLE_ADDRESS_BOOK') . " ab
										left join " . $this->cf->get('TABLE_ZONES') . " z on (ab.entry_zone_id = z.zone_id)
										where ab.customers_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'
										and ab.address_book_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'";
			} else {
				$tax_address_query = "select ab.entry_country_id, ab.entry_zone_id
										from " . $this->cf->get('TABLE_ADDRESS_BOOK') . " ab
										left join " . $this->cf->get('TABLE_ZONES') . " z on (ab.entry_zone_id = z.zone_id)
										where ab.customers_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'
										and ab.address_book_id = '" . (int)$this->cf->get('POS_DEFAULT_CUSTOMER') . "'";
			}
		}
		return $this->db->execute($tax_address_query);
	}
	
	public function getTaxRate($class_id, $country_id = -1, $zone_id = -1) {
		
		if ( ($country_id == -1) && ($zone_id == -1) ) {
			$country_id = $this->cf->get('STORE_COUNTRY');
			$zone_id = $this->cf->get('STORE_ZONE');
		}
		
		$tax_query = 	"select sum(tax_rate) as tax_rate
						from (" . $this->cf->get('TABLE_TAX_RATES') . " tr
						left join " . $this->cf->get('TABLE_ZONES_TO_GEO_ZONES') . " za on (tr.tax_zone_id = za.geo_zone_id)
						left join " . $this->cf->get('TABLE_GEO_ZONES') . " tz on (tz.geo_zone_id = tr.tax_zone_id) )
						where (za.zone_country_id is null
						or za.zone_country_id = 0
						or za.zone_country_id = '" . (int)$country_id . "')
						and (za.zone_id is null
						or za.zone_id = 0
						or za.zone_id = '" . (int)$zone_id . "')
						and tr.tax_class_id = '" . (int)$class_id . "'
						group by tr.tax_priority";
		
		$tax = $this->db->execute($tax_query);
		
		if ($tax->recordCount() > 0) {
			$tax_multiplier = 1.0;
			while (!$tax->EOF) {
				$tax_multiplier *= 1.0 + ($tax->fields['tax_rate'] / 100);
				$tax->moveNext();
			}
			$fulltax = ($tax_multiplier - 1.0) * 100;
			return (int)$fulltax;
		} else {
			return 0;
		}
	}
	
	public function getTaxDescription($class_id, $country_id = -1, $zone_id = -1) {
		
		if ( ($country_id == -1) && ($zone_id == -1) ) {
			$country_id = $this->cf->get('STORE_COUNTRY');
			$zone_id = $this->cf->get('STORE_ZONE');
		}
		
		$tax_query =	"select tax_description
						from (" . $this->cf->get('TABLE_TAX_RATES') . " tr
						left join " . $this->cf->get('TABLE_ZONES_TO_GEO_ZONES') . " za on (tr.tax_zone_id = za.geo_zone_id)
						left join " . $this->cf->get('TABLE_GEO_ZONES') . " tz on (tz.geo_zone_id = tr.tax_zone_id) )
						where (za.zone_country_id is null or za.zone_country_id = 0
						or za.zone_country_id = '" . (int)$country_id . "')
						and (za.zone_id is null
						or za.zone_id = 0
						or za.zone_id = '" . (int)$zone_id . "')
						and tr.tax_class_id = '" . (int)$class_id . "'
						order by tr.tax_priority";
		
		$tax = $this->db->execute($tax_query);
		
		if ($tax->recordCount() > 0) {
			$tax_description = '';
			while (!$tax->EOF) {
				$tax_description .= $tax->fields['tax_description'] . ' + ';
				$tax->moveNext();
			}
			$tax_description = substr($tax_description, 0, -3);
			
			return $tax_description;
		} else {
			return "No taxes found";
		}
	}
	
	public function getDisplayWithTax() {
		if ($this->displayPriceWithTax == "true") return true;
		else return false;
	}
	
	public function addTax($price, $tax) {
		if ( ($this->displayPriceWithTax == 'true') && ($tax > 0) ) {
			return round($price, $this->currencies->currencies[$this->defaultCurrency]['decimal_places']) + $this->calculateTax($price, $tax);
		} else {
			return round($price, $this->currencies->currencies[$this->defaultCurrency]['decimal_places']);
		}
		
	/* Original Implementaion
	function addTax($netPrice, $taxPercentage) {
		$grossPrice = $netPrice + ($netPrice / 100 * $taxPercentage);
		return round($grossPrice, 2);
	}
	*/
		
	}
	
	function calculateTax($price, $tax) {
		return round($price * $tax / 100, $this->currencies->currencies[$this->defaultCurrency]['decimal_places']);
	}
}
?>
